home *** CD-ROM | disk | FTP | other *** search
- /*
- * gmemusage.c
- *
- * Reveal system memory usage
- *
- * Copyright 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
-
- #include <sys/types.h>
- #include <sys/time.h>
- #include <sys/sysmp.h>
- #include <sys/wait.h>
-
- #include <unistd.h>
- #include <stdio.h>
- #include <getopt.h>
- #include <string.h>
- #include <malloc.h>
- #include <stdlib.h>
- #include <bstring.h>
-
- #include <gl/gl.h>
- #include <gl/device.h>
-
- #include "process.h"
- #include "draw.h"
- #include "inode.h"
- #include "print.h"
-
- #define DEF_THRESH 500
- #define DEF_DELTA 50
-
- /*
- * Set to 1 once the inode table has been initialized
- */
- static int inodesInitted = 0;
-
- /*
- * static void
- * PlaySound(char *sound)
- *
- * Description:
- * run playaiff asynchronously to play a sound
- *
- * Parameters:
- * sound
- */
-
- static void
- PlaySound(char *sound)
- {
- static int firstTime = 1;
- static int ok = 0;
- static pid_t pid;
- int fd, stat;
-
- if (firstTime) {
- firstTime = 0;
- if (sound) {
- if (access("/usr/sbin/playaiff", F_OK | X_OK) == -1) {
- perror("/usr/sbin/playiff");
- return;
- }
-
- if (access(sound, F_OK) == -1) {
- perror(sound);
- return;
- }
- ok = 1;
- }
- }
-
- if (!ok) {
- return;
- }
-
- /*
- * Don't interrupt it if the last one is still playing
- */
- if (waitpid(pid, &stat, WNOHANG) == 0) {
- return;
- }
-
- if (pid = fork()) {
- return;
- }
-
- for (fd = getdtablesize(); fd > 2; fd--) {
- close(fd);
- }
-
- setuid(getuid()); /* avoid security problems */
- execl("/usr/sbin/playaiff", "playaiff", sound, NULL);
- exit(-1);
- }
-
- /*
- * static void
- * InitInodes(void)
- *
- * Description:
- * Make sure inodes are initted. This gets called from two
- * different places, and the flag inodesInitted is global.
- */
-
- static void
- InitInodes(void)
- {
- if (!inodesInitted) {
- WaitMessage("Initializing inode lookup table...", NULL);
- InodeInit();
- inodesInitted = 1;
- }
- }
-
- /*
- * char *
- * HandleMouse(PROGRAM *usage, long mousex, long mousey, int *procMode,
- * int dragging)
- *
- * Description:
- * Handle mouse events. We use the mouse to select bars to
- * display detailed breakdowns, and to leave detailed mode. The
- * passed in procMode gets cleared if we should leave detailed
- * mode.
- *
- * Parameters:
- * usage current all programs usage being displayed
- * mousex mouse horiz position
- * mousey mouse vert position
- * procMode pointer to variable that says whether we're already
- * in procMode
- * dragging 1 if we're dragging
- *
- * Returns:
- * pointer to name of program selected
- */
-
- char *
- HandleMouse(PROGRAM *usage, long mousex, long mousey, int *procMode,
- int dragging)
- {
- static char *oldProcName;
- char *procName;
- long originx, originy;
-
- getorigin(&originx, &originy);
- mousex -= originx;
- mousey -= originy;
-
- procName = Select(usage, mousex, mousey, procMode, dragging);
-
- if (!procName && *procMode) {
- return oldProcName;
- }
-
- if (procName) {
- if (!inodesInitted && strcmp(procName, IRIX) != 0) {
- if (dragging) {
- unqdevice(MOUSEX);
- unqdevice(MOUSEY);
- }
- InitInodes();
- if (dragging) {
- qdevice(MOUSEX);
- qdevice(MOUSEY);
- }
- }
- *procMode = 1;
- if (oldProcName) {
- free(oldProcName);
- }
- oldProcName = procName;
- }
-
- return procName;
- }
-
- int
- main(int argc, char *argv[])
- {
- int glfd, opt, threshDelta = DEF_DELTA, doHelp = 0, doFreeze = 0;
- int gotInput, doProcMode = 0, needNewColors = 0, inodesInitted = 0;
- int barTotal, progBarTotal, numBars, numProgBars, dragging = 0;
- int oldProgBarTotal, soundThresh = 12, pgsize;
- fd_set fds, tfds;
- PROGRAM *usage = NULL, *lastUsage = NULL;
- PROGRAM *progUsage = NULL, *lastProgUsage = NULL;
- long physMem, freeMem, threshHold = DEF_THRESH;
- long dev, originx, originy;
- short value, mousex, mousey;
- struct timeval tv;
- char *str, *procName = NULL, *newProcName = NULL;
- PROGNAME *progNames = NULL, *name, *prev = NULL;
- UsageType type, newType;
- SecondType stype, newStype;
- long usecTimeOut = 500000, secTimeOut = 0, msecTimeOut;
- struct rminfo rminfo;
- char *usageSound = getenv("USAGESOUND");
-
- if (geteuid() != 0) {
- fprintf(stderr, "%s must be run as root or it must be setuid root.\n",
- argv[0]);
- exit(1);
- }
-
- type = newType = Physical;
- stype = newStype = None;
- /*
- * Process command line arguments
- */
- opterr = 0;
- while ((opt = getopt(argc, argv, "a:g:i:d:mprst:u")) != EOF) {
- switch (opt) {
- case 'a':
- usageSound = optarg;
- break;
- case 'g':
- soundThresh = atoi(optarg);
- break;
- case 'i':
- msecTimeOut = atoi(optarg);
- secTimeOut = msecTimeOut / 1000;
- usecTimeOut = 1000 * (msecTimeOut % 1000);
- break;
- case 'd':
- threshDelta = atoi(optarg);
- if (threshDelta <= 0) {
- fprintf(stderr, "Resetting delta from %d\n", threshDelta);
- threshDelta = DEF_DELTA;
- }
- break;
- case 'm':
- type = newType = MappedObjects;
- break;
- case 'p':
- type = newType = Physical;
- break;
- case 'r':
- type = newType = Resident;
- break;
- case 's':
- type = newType = Size;
- break;
- case 't':
- threshHold = atoi(optarg);
- break;
- case 'u':
- InvalidateInodeTable();
- break;
- default:
- doHelp = 1;
- }
- }
-
- while (optind < argc) {
- name = malloc(sizeof *name);
- name->name = argv[optind];
- name->next = NULL;
-
- if (prev) {
- prev->next = name;
- } else {
- progNames = name;
- }
- prev = name;
- optind++;
- }
-
- if (sysmp(MP_SAGET, MPSA_RMINFO, &rminfo, sizeof rminfo) == -1) {
- perror("sysmp");
- return 1;
- }
-
- pgsize = getpagesize()/1024;
-
- physMem = rminfo.physmem * pgsize;
-
- foreground();
- Init(progNames, threshHold);
-
- glfd = qgetfd();
-
- qdevice(ESCKEY);
- qdevice(HKEY);
- qdevice(MKEY);
- qdevice(PKEY);
- qdevice(RKEY);
- qdevice(SKEY);
- qdevice(TKEY);
- qdevice(VKEY);
- qdevice(UPARROWKEY);
- qdevice(DOWNARROWKEY);
- qdevice(SPACEKEY);
- qdevice(WINFREEZE);
- qdevice(WINTHAW);
- qdevice(LEFTMOUSE);
- tie(LEFTMOUSE, MOUSEX, MOUSEY);
-
- FD_ZERO(&fds);
- FD_SET(glfd, &fds);
-
- tv.tv_sec = secTimeOut;
- tv.tv_usec = usecTimeOut;
-
- gotInput = 0;
-
- if (type == MappedObjects) {
- InitInodes();
- }
-
- while (1) {
- /*
- * Draw the window, either help or the usage chart
- */
- if (!doFreeze) {
- if (doHelp) {
- Help();
- } else {
- /*
- * If the user pressed a key that we can deal with without
- * getting all our data again, just redraw.
- */
- if (!gotInput || type != newType || stype != newStype) {
- stype = newStype;
- type = newType;
- if (lastUsage) {
- FreeUsage(lastUsage);
- }
- lastUsage = usage;
- if (lastProgUsage) {
- FreeUsage(lastProgUsage);
- }
- lastProgUsage = progUsage;
-
- if (type == MappedObjects) {
- GetObjInfo(doProcMode ? procName : NULL,
- &usage, &progUsage);
- } else {
- GetProcInfo(doProcMode ? procName : NULL,
- &usage, &progUsage);
- }
-
- if (sysmp(MP_SAGET, MPSA_RMINFO, &rminfo,
- sizeof rminfo) == -1) {
- perror("sysmp");
- return 1;
- }
- freeMem = rminfo.freemem * pgsize;
-
- if (usage) {
- usage = DrawSetup(usage,
- needNewColors ? NULL : lastUsage,
- physMem, freeMem, type, stype, 1,
- &barTotal, &numBars);
- }
- if (progUsage) {
- progUsage = DrawSetup(progUsage,
- needNewColors ?
- NULL : lastProgUsage,
- physMem, freeMem,
- type, stype, 0, &progBarTotal,
- &numProgBars);
- if (usageSound) {
- if (oldProgBarTotal == 0 ||
- oldProgBarTotal > progBarTotal) {
- oldProgBarTotal = progBarTotal;
- } else if (progBarTotal >
- oldProgBarTotal + soundThresh) {
- PlaySound(usageSound);
- oldProgBarTotal = progBarTotal;
- }
- }
- }
- if (doProcMode && !progUsage) {
- doProcMode = 0;
- }
- needNewColors = 0;
- }
-
- if (doProcMode && progUsage) {
- DrawShadow(usage, barTotal, procName);
- Draw(progUsage, progBarTotal, numProgBars,
- procName, type, stype);
- } else if (usage) {
- Draw(usage, barTotal, numBars, NULL, type, stype);
- }
- gotInput = 0;
- }
- }
-
- /*
- * Wait for GL events, timing out after half a second
- */
- tfds = fds;
- if (select(glfd + 1, &tfds, NULL, NULL,
- (doHelp || doFreeze) ? NULL : &tv) < 0) {
- perror("select");
- return 1;
- }
-
- /*
- * Process GL events
- */
- if (FD_ISSET(glfd, &tfds)) {
- while (qtest()) {
- dev = qread(&value);
- switch (dev) {
- case HKEY:
- /*
- * Help
- */
- if (value == 0) {
- doHelp = 1;
- needNewColors = 1;
- }
- break;
- case SPACEKEY:
- /*
- * End of help
- */
- if (value == 0) {
- doProcMode = 0;
- doHelp = 0;
- }
- break;
- case MKEY:
- if (value == 0) {
- newStype = stype % Phys;
- newType = MappedObjects;
- doHelp = 0;
- InitInodes();
- needNewColors = 1;
- }
- break;
- case PKEY:
- /*
- * Physical Memory Breakdown
- */
- if (value == 0) {
- if (procName && strcmp(procName, IRIX) == 0) {
- newStype = None;
- } else {
- newStype = stype % Phys;
- }
- newType = Physical;
- doHelp = 0;
- needNewColors = 1;
- }
- break;
- case RKEY:
- /*
- * Resident Sizes of Processes
- */
- if (value == 0) {
- if (!doProcMode
- || strcmp(procName, IRIX) != 0) {
- newStype = stype % Res;
- newType = Resident;
- doHelp = 0;
- needNewColors = 1;
- }
- }
- break;
- case SKEY:
- /*
- * Total Sizes of Processes
- */
- if (value == 0) {
- if (!doProcMode
- || strcmp(procName, IRIX) != 0) {
- newStype = stype % (Res + 1);
- newType = Size;
- doHelp = 0;
- needNewColors = 1;
- }
- }
- break;
- case TKEY:
- if (value == 0) {
- if (doProcMode && progUsage) {
- PrintUsage(stdout, PRProc, progUsage, procName);
- } else if (usage) {
- PrintUsage(stdout,
- type == MappedObjects ? PRMaps : PRAll,
- usage, NULL);
- }
- }
- break;
- case VKEY:
- if (value == 0) {
- doHelp = 0;
- newStype = stype + 1;
- switch (type) {
- case Size:
- newStype %= Res + 1;
- break;
- case Resident:
- newStype %= Res;
- break;
- case Physical:
- if (procName && strcmp(procName, IRIX) == 0) {
- newStype = None;
- break;
- }
- /* intentional fall through */
- case MappedObjects:
- newStype %= Phys;
- break;
- default:
- newStype = None;
- break;
- }
- }
- break;
- case ESCKEY:
- /*
- * Exit
- */
- if (value == 0) {
- exit(0);
- }
- break;
- case REDRAW:
- /*
- * Resize event
- */
- gotInput = 1;
- Resize();
- break;
- case UPARROWKEY:
- /*
- * Increase threshhold
- */
- if (value == 0) {
- if (threshHold == 1)
- threshHold = 0;
- threshHold += threshDelta;
- SetThreshHold(threshHold);
- doHelp = 0;
- needNewColors = 1;
- }
- break;
- case DOWNARROWKEY:
- /*
- * Decrease threshhold
- */
- if (value == 0) {
- if (threshHold == threshDelta)
- threshHold = 1;
- else
- threshHold -= threshDelta;
- if (threshHold < 0) {
- threshHold = 0;
- }
- SetThreshHold(threshHold);
- doHelp = 0;
- needNewColors = 1;
- }
- break;
- case MOUSEX:
- needNewColors = 1;
- mousex = value;
- procName = HandleMouse(usage, mousex, mousey,
- &doProcMode, 1);
- oldProgBarTotal = 0;
- break;
- case MOUSEY:
- needNewColors = 1;
- mousey = value;
- procName = HandleMouse(usage, mousex, mousey,
- &doProcMode, 1);
- oldProgBarTotal = 0;
- break;
- case LEFTMOUSE:
- needNewColors = 1;
- (void)qread(&mousex);
- (void)qread(&mousey);
- if (usage && !doHelp && value) {
- /*
- * This extra flag prevents switching bars if
- * the user is moving the mouse at the same
- * time that a bar is selected; if we start
- * queueing mouse motion right away, we'll
- * shift bars because off the vertical offset
- * of the shadow chart.
- */
- int prevDoProcMode = doProcMode;
- procName = HandleMouse(usage, mousex, mousey,
- &doProcMode, dragging);
- oldProgBarTotal = 0;
- if (procName && strcmp(procName, IRIX) == 0) {
- newStype = None;
- }
- if (prevDoProcMode && !dragging) {
- qdevice(MOUSEX);
- qdevice(MOUSEY);
- dragging = 1;
- }
- }
- if (!value && dragging) {
- unqdevice(MOUSEX);
- unqdevice(MOUSEY);
- dragging = 0;
- }
- break;
- case WINFREEZE:
- doFreeze = 1;
- break;
- case WINTHAW:
- doFreeze = 0;
- break;
- default:
- break;
- }
- }
- }
- }
- return 0;
- }
-